﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LowLevelGraphics.ColorSpaces;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Converts a picture in a given color space and then back to rgb
    /// Pixels that changed are marked.
    /// 
    /// This is more to debug I guess nowadays 
    /// Maybe I'll delete this filter
    /// </summary>
    public class RecolorizeColorSpace : BaseForeBackgroundColorFilter
    {
        protected Type m_TypeOfColorSpace = typeof(void);
        protected bool m_bShowChanges = false;

        /// <summary>
        /// default constructor
        /// </summary>
        public RecolorizeColorSpace()
            : this(typeof(sRGB))
        {
        }

        /// <summary>
        /// default constructor
        /// </summary>
        /// <param name="_type"></param>
        public RecolorizeColorSpace(Type _type)
        {
            this.m_TypeOfColorSpace = _type;
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_recolorizeColorSpace"></param>
        internal RecolorizeColorSpace(RecolorizeColorSpace _recolorizeColorSpace)
        {
            this.m_TypeOfColorSpace = _recolorizeColorSpace.m_TypeOfColorSpace;
            m_bShowChanges = _recolorizeColorSpace.m_bShowChanges;
        }

        /// <summary>
        /// Gets or sets type of color space
        /// </summary>
        public Type TypeOfColorSpace
        {
            get { return m_TypeOfColorSpace; }
            set { m_TypeOfColorSpace = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [show changes].
        /// </summary>
        /// <value><c>true</c> if [show changes]; otherwise, <c>false</c>.</value>
        public bool ShowChanges
        {
            get { return m_bShowChanges; }
            set { m_bShowChanges = value; }
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            //Don't create this in here all the time to speed it up.
            AbstractColorSpace abstractColorSpace = (AbstractColorSpace)Activator.CreateInstance(m_TypeOfColorSpace, Color.Blue);

            UnsafeBitmap bitmap = _bitmap;

            int nWidth = bitmap.Width;
            int nHeight = bitmap.Height;

            Color color = Color.Transparent;
            Color colorNew = Color.Transparent;

            int y = 0;
            int x = 0;

            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    color = bitmap.GetPixel(x, y);
                    abstractColorSpace.Color = color;
                    colorNew = abstractColorSpace.ToColor();
                    if (m_bShowChanges)
                    {
                        bitmap.SetPixel(x, y, color == colorNew ? m_ColorForeground : m_ColorBackground);
                    }
                    else
                    {
                        //only to debug
                        //int nDist = ColorFunctions.Distance(color, colorNew);
                        bitmap.SetPixel(x, y, colorNew);
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new RecolorizeColorSpace(this);
        }
    }
}
